from jira import JIRA, Issue
import re, os

import datetime

def logprint(*args, sep=' ', end='\n'):
    print(datetime.datetime.now(),*args, sep=' ', end='\n')

AS_TYPE_FS1TA='FS1TA'
AS_TYPE_CP1='CP1'
AS_TYPE_CP2='CP2'

WORK_TYPE_FS1TA='FS1TA'
WORK_TYPE_CP1='CP1'
WORK_TYPE_CP2='CP2'
WORK_TYPE_SUB='SUB'

SPEC_TYPE_FS1TA='Pre-analysis'
SPEC_TYPE_CP1='CP1'
SPEC_TYPE_CP2='CP2'

ACTIVITY_TYPE_FS1TA='Pre-analysis'
ACTIVITY_TYPE_SFS='System Specification'

ISSUE_TYPE_FT_S='FT'
ISSUE_TYPE_SI_S='SI'
ISSUE_TYPE_EI_S='EI'
ISSUE_TYPE_CA_S='CA'

ISSUE_TYPE_FT_L='Customer Feature'
ISSUE_TYPE_SI_L='System Item'
ISSUE_TYPE_EI_L='Entity Item'
ISSUE_TYPE_CA_L='Competence Area'
ISSUE_TYPE_EPIC_L='Epic'
ISSUE_TYPE_STA_L='System Technical Analysis'
ISSUE_TYPE_ETA_L='Entity Technical Analysis'
ISSUE_TYPE_EE_L='Effort Estimation'

def print_header(issue:Issue):
    if str(issue.fields.issuetype) == ISSUE_TYPE_FT_L:
        header=""
    elif str(issue.fields.issuetype) == ISSUE_TYPE_SI_L:
        header="    "
    elif str(issue.fields.issuetype) == ISSUE_TYPE_EI_L:
        header="        "
    elif str(issue.fields.issuetype) == ISSUE_TYPE_CA_L:
        header="            "
    elif str(issue.fields.issuetype) == ISSUE_TYPE_EPIC_L:
        header="                "
    else:
        print("UNKNOWN ISSUE TYPE", issue.fields.issuetype)
        header="        "
    return header

def print_basic_info(issue:Issue):
    print(print_header(issue), "%s    %s    %s"%(issue.key, issue.fields.status, issue.fields.summary))

DOMAIN_LIST=[
    'SiSo',
    'CallHandling',
    'QoSEndUserExp',
    'RadioPerf',
    'PerfCapa',
    'Cloud',
    'E2EOperability-Basic',
	'E2EOperability-RNL',
    'E2EOperability-Sec',
    'E2EOperability-Sync',
    'E2ETrs-Basic',
    'E2ETrs-Sec',
    'BB_HWI',
    'RU_HWI',
    'SmallCells',
    'Airphone'
]

DOMAIN_CA_MAP={
    'SiSo': '5GRAN SysSpecs Siso',
    'CallHandling': '5GRAN SysSpecs CP',
    'QoSEndUserExp': '5GRAN SysSpecs UP',
    'RadioPerf': '5GRAN SysSpecs UP',
    'PerfCapa': '5GRAN SysSpecs UP',
    'Cloud': '5GRAN SysSpecs Cloud',
    'E2EOperability-Basic': '5GRAN SysSpecs OAM-BTS/OSS',
	'E2EOperability-RNL': '5GRAN SysSpecs OAM-BTS/OSS',
    'E2EOperability-Sec': '5GRAN SysSpecs OAM-Security',
    'E2EOperability-Sync': '5GRAN SysSpecs OAM-Synch',
    'E2ETrs-Basic': '5GRAN SysSpecs TRS',
    'E2ETrs-Sec': '5GRAN SysSpecs TRS',
    'BB_HWI': '5GRAN SysSpecs Siso',
    'RU_HWI': '5GRAN SysSpecs RU',
    'SmallCells': 'SC SFS'
}

def init_jira_connection():
    url, user, passwd = get_jira_config()
    jira_obj = JIRA(server=url, auth=(user, passwd))
    return jira_obj

def init_cr_connection():
    crurl, user, passwd = get_cr_config()
    jira_obj = JIRA(server=crurl, auth=(user, passwd))
    return jira_obj

def get_task_jql(task):
    import configparser
    config = configparser.ConfigParser()
    config.read_file(open(get_config_file()))

    return config.get(task, 'JQL')

def get_child_items(jira:JIRA, issue:Issue):
    childs = []
    for issue_linked in issue.fields.issuelinks:
        if (issue_linked.type.name == 'Parent') and hasattr(issue_linked, 'outwardIssue'):
            child = jira.issue(issue_linked.outwardIssue.key)
            childs.append(child)
    return childs

def parse_feature_title(issue:Issue):
    if issue.fields.issuetype.name != ISSUE_TYPE_FT_L:
        raise Exception("Given Issue is not a Customer Feature", issue.fields.issuetype)

    summary=issue.fields.summary
    reobj=re.compile('^(5GC00[0-9]{4}|CB00[0-9]{4}-5G) (.*)')
    match=reobj.search(summary)
    if not match:
        raise Exception("Unrecognized feature", summary)
    elif len(match.groups()) != 2:
        raise Exception("Unrecognized feature", summary)
    return match.group(1),match.group(2)

def get_feature_via_id(jira:JIRA, feature_id:str):
    jql='type = "Customer Feature" AND "Feature ID" ~ "%s"'%feature_id
    issue_list = jira.search_issues(jql, maxResults=1,validate_query=True)
    if not issue_list:
        raise Exception('Invalid feature ID', feature_id)
    return issue_list[0]

def readConfig():
    import configparser
    config = configparser.ConfigParser()
    config.read_file(open(get_config_file()))

    return config.get('Account', 'url'), config.get('Account', 'user'), config.get('Account', 'passwd')

def get_jira_config():
    import configparser
    config = configparser.ConfigParser()
    config.read_file(open(get_config_file()))

    return config.get('Account', 'url'), config.get('Account', 'user'), config.get('Account', 'passwd')

def get_cr_config():
    import configparser
    config = configparser.ConfigParser()
    config.read_file(open(get_config_file()))

    return config.get('Account', 'cr'), config.get('Account', 'user'), config.get('Account', 'passwd')

def get_config_file():
    file = os.path.split(os.path.abspath(__file__))[0] + "/config.ini"
    return file

def getNiddTasks():
    import configparser
    config = configparser.ConfigParser()
    config.read_file(open(get_config_file()))
    nidd_tasks=[]

    for section in config:
        if section.find("NIDD") >= 0:
            nidd_tasks.append(section)
    return nidd_tasks

def getTask(task):
    import configparser
    config = configparser.ConfigParser()
    config.read_file(open(get_config_file()))

    return config.get(task, 'JQL'), config.get(task, "File")

def load_task_jql(task):
    import configparser
    config = configparser.ConfigParser()
    config.read_file(open(get_config_file()))

    return config.get(task, 'JQL')

def getCfamLeaderListFile():
    import configparser
    config = configparser.ConfigParser()
    config.read_file(open(get_config_file()))

    return config.get('CFAM_Leader', 'File')

def getCfamStatusFile():
    import configparser
    config = configparser.ConfigParser()
    config.read_file(open(get_config_file()))

    return config.get('CFAM_Status', 'File')

def getStatus(issue:Issue):
    return str(issue.fields.status.name)

def get_issue_status(issue:Issue):
    if not hasattr(issue.fields, 'status'):
        raise Exception("No status field, add status in field list", issue.key)
    return str(issue.fields.status.name)

def get_issue_lables(issue):
    if not hasattr(issue.fields, 'labels'):
        raise Exception("No labels field, add labels in field list", issue.key)

    labels = ''
    if issue.fields.labels:
        for label in issue.fields.labels:
            if labels == '':
                labels = label
            else:
                labels = labels + ', '+label
    return labels

def get_summary(issue:Issue):
    if not hasattr(issue.fields, 'summary'):
        raise Exception("No summary field, add summary in field list", issue.key)
    return str(issue.fields.summary).rstrip().lstrip()

def get_assignee_email(issue:Issue):
    if not hasattr(issue.fields, 'assignee'):
        raise Exception("No assignee field for the issue, add assignee in field list")

    if issue.fields.assignee:
        return issue.fields.assignee.emailAddress
    return ''

def getAssignee(issue:Issue):
    if not hasattr(issue.fields, 'assignee'):
        raise Exception("No assignee field for the issue, add assignee in field list")

    if issue.fields.assignee:
        return issue.fields.assignee.displayName
    return ''
	
def get_assignee(issue:Issue):
    if not hasattr(issue.fields, 'assignee'):
        raise Exception("No assignee field for the issue, add assignee in field list")

    if issue.fields.assignee:
        #print(issue.raw['fields']['assignee'])
        return issue.fields.assignee.displayName
    return ''

def getSfsStartFb(issue:Issue):
    if issue.raw['fields']['customfield_38738']:
        fb = issue.raw['fields']['customfield_38738']
    else:
        fb = ""
    return fb

def getSfsEndFb(issue:Issue):
    if issue.raw['fields']['customfield_38739']:
        fb = issue.raw['fields']['customfield_38739']
    else:
        fb = ""
    return fb

def getEfsStartFb(issue:Issue):
    if issue.raw['fields']['customfield_38740']:
        fb = issue.raw['fields']['customfield_38740']
    else:
        fb = ""
    return fb

def getEfsEndFb(issue:Issue):
    if issue.raw['fields']['customfield_38741']:
        fb = issue.raw['fields']['customfield_38741']
    else:
        fb = ""
    return fb

def getSwStartFb(issue:Issue):
    if issue.raw['fields']['customfield_38746']:
        fb = issue.raw['fields']['customfield_38746']
    else:
        fb = ""
    return fb

def getSwEndFb(issue:Issue):
    if issue.raw['fields']['customfield_38747']:
        fb = issue.raw['fields']['customfield_38747']
    else:
        fb = ""
    return fb

def getEtStartFb(issue:Issue):
    if issue.raw['fields']['customfield_38744']:
        fb = issue.raw['fields']['customfield_38744']
    else:
        fb = ""
    return fb

def getEtEndFb(issue:Issue):
    if issue.raw['fields']['customfield_38745']:
        fb = issue.raw['fields']['customfield_38745']
    else:
        fb = ""
    return fb

def get_feature_project_owner(issue:Issue):
    #print("Feature Project Owner", issue.raw['fields']['customfield_38695'])
    if issue.raw['fields']['customfield_38695']:
        fpo = issue.raw['fields']['customfield_38695']['displayName']
    else:
        fpo = ""
    return fpo

def get_priority(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38716'):
        raise Exception('No Bussiness Priority Field, add customfield_38716 in field list', issue.key)
    if issue.raw['fields']['customfield_38716']:
        return int(issue.fields.customfield_38716)
    else:
        return ''

def get_rnd_priority(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38721'):
        raise Exception('No R&D Priority Field, add customfield_38721 in field list', issue.key)
    if issue.raw['fields']['customfield_38721']:
        return int(issue.fields.customfield_38721)
    else:
        return 0

def get_feature_project_owner(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38695'):
        raise Exception("No Feature Project Owner Field, add customfield_38695 in field list", issue.key)

    if issue.raw['fields']['customfield_38695']:
        fpo = issue.fields.customfield_38695.displayName
    else:
        fpo = ''
    return fpo

def get_contact_person(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38698'):
        raise Exception("No contact person field, add customfield_38698 in field list", issue.key)

    contact_person = ''
    if issue.fields.customfield_38698:
        for contact in issue.fields.customfield_38698:
            if contact_person == '':
                contact_person = contact.displayName
            else:
                contact_person = '%s, %s'%(contact_person, contact.displayName)
    return contact_person

def get_planned_system_release(issue:Issue):
    if not hasattr(issue.fields,"customfield_38724"):
        raise Exception("No Planned System Release Field, add customfield_38724 in field list", issue.key)
    release = ''
    if issue.fields.customfield_38724:
        for r in issue.fields.customfield_38724:
            return r.value
    return release

def update_planned_system_release(issue:Issue, release:str):
    try:
        issue.update({'customfield_38724': [{'value': release}]})
    except:
        pass

def update_item_id(issue:Issue, itemid:str):
    issue.update({'customfield_38702':itemid})

def get_target_releases(issue:Issue):
    if not hasattr(issue.fields, "customfield_38710"):
        raise Exception("No Target Releases Field, add customfield_38710 in field list", issue.key)

    if issue.fields.customfield_38710:
        return issue.fields.customfield_38710
    else:
        return ''

def get_domain_planning(issue:Issue):
    domain = get_domain(issue)
    return get_planning_via_domain(domain)

def get_planning_via_domain(domain:str):
    domain_map = {
        'SiSo':'Xia, Chunguang (NSB - CN/Hangzhou)',
        'CallHandling':'Bn, Anupama (Nokia - IN/Bangalore)',
        'QoSEndUserExp':'Godard, Tania (Nokia - FR/Paris-Saclay)',
        'QosEndUserExp':'Godard, Tania (Nokia - FR/Paris-Saclay)',
        'RadioPerf':'Godard, Tania (Nokia - FR/Paris-Saclay)',
        'PerfCapa':'Djupsund, Markus (Nokia - FI/Oulu)',
        'Cloud':'Zhou, Lan (NSB - CN/Hangzhou) ',
        'E2EOperability-Basic':'Burzawa, Grzegorz (Nokia - PL/Wroclaw)',
		'E2EOperability-RNL':'Bronzini, Patrick (Nokia - FR/Paris-Saclay)',
        'E2EOperability-Sec':'Huet, Francois (Nokia - FR/Paris-Saclay)',
        'E2EOperability-Sync':'Huet, Francois (Nokia - FR/Paris-Saclay)',
        'E2ETrs-Basic':'Metsala, Esa (Nokia - FI/Espoo)',
        'E2ETrs-Sec':'Huet, Francois (Nokia - FR/Paris-Saclay)',
        'BB_HWI':'Zhou, Xin 3. (NSB - CN/Hangzhou)',
        'RU_HWI':'Gustrau, Joerg (Nokia - DE/Ulm)',
        'SmallCells':'Dahi, Arezoo (Nokia - US/Naperville)'
    }
    if domain not in domain_map.keys():
        name = ""
    else:
        name=domain_map[domain]
    return name

def get_feature_id(issue:Issue):
    if not hasattr(issue.fields, 'customfield_37381'):
        raise Exception('No Feature ID field, add customfield_37381 in field list')
    if issue.fields.customfield_37381:
        return issue.fields.customfield_37381
    else:
        return ''

def getFeatureIdFromSummary(issue:Issue):
    summary = issue.fields.summary
    pos = summary.find('5GC00')
    if pos >= 0:
        id = summary[pos:pos+9]
    else:
        id = ""
    #print("Feature ID：", id)
    return id

def get_feature_id_from_summary(issue:Issue):
    summary = issue.fields.summary
    reobj = re.compile('^(5GC00[0-9]{4}|CB00[0-9]{4}-5G) (.*)')
    match = reobj.search(summary)
    if not match:
        raise Exception("Unrecognized feature", summary)
    elif len(match.groups()) != 2:
        raise Exception("Unrecognized feature", summary)
    return match.group(1)

def get_cp1_status_via_feature_id(jiraobj:Issue, feature_id:str):
    jql = 'issuetype = "Competence Area" AND "Specification Type" = CP1 AND "Feature ID" ~ "%s"' % feature_id
    print(jql)
    issueList = jiraobj.search_issues(jql, maxResults=1, validate_query=True, fields=['status'])

    print(len(issueList))
    if len(issueList):
        print(issueList[0].fields.status)
        return str(issueList[0].fields.status)
    else:
        return 'New'

def get_nidd_impact(issue:Issue):
    if issue.raw['fields']['customfield_38764']:
        info = issue.raw['fields']['customfield_38764']['value']
    else:
        info = ""
    return info

def getExpectFB(issue:Issue):
    if issue.raw['fields']['customfield_39390']:
        expFb = issue.raw['fields']['customfield_39390']['value']
    else:
        expFb = ""
    return expFb

def getCmStatus(issue:Issue):
    cm = str(issue.raw['fields']['customfield_39590'])
    if issue.raw['fields']['customfield_39590']:
        cm = issue.raw['fields']['customfield_39590']['value']
    else:
        cm = ""
    return cm

def getSpecType(issue:Issue):
    specType = ""
    if issue.raw['fields']['customfield_38753']:
        specType = issue.raw['fields']['customfield_38753']['value']

    return str(specType)

def get_specification_type(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38753'):
        raise Exception("No Specification Type Field, add customfield_38753 in field list")

    if issue.fields.customfield_38753:
        return issue.fields.customfield_38753.value
    return ''

def getFmStatus(issue:Issue):
    fm = str(issue.raw['fields']['customfield_39592'])
    if issue.raw['fields']['customfield_39592']:
        fm = issue.raw['fields']['customfield_39592']['value']
    else:
        fm = ""
    return fm

def getPmStatus(issue:Issue):
    pm = str(issue.raw['fields']['customfield_39591'])
    if issue.raw['fields']['customfield_39591']:
        pm = issue.raw['fields']['customfield_39591']['value']
    else:
        pm = ""
    return pm

def getStartFb(issue:Issue):
    #customfield_38694
    #print("Start FB:",issue.raw['fields']['customfield_38694'])
    if issue.raw['fields']['customfield_38694']:
        fb = str(issue.raw['fields']['customfield_38694'])
    else:
        fb = ""
    return fb

def getEndFb(issue:Issue):
    #customfield_38693
    #print("End FB:",issue.raw['fields']['customfield_38693'])
    if issue.raw['fields']['customfield_38693']:
        fb = str(issue.raw['fields']['customfield_38693'])
    else:
        fb = ""
    return fb

def get_start_fb(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38694'):
        raise Exception('No Start FB Field, add customfield_38694 in field list', issue.key)
    if issue.raw['fields']['customfield_38694']:
        return issue.fields.customfield_38694
    else:
        return ''

def get_end_fb(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38693'):
        raise Exception('No End FB Field, add customfield_38693 in field list', issue.key)
    if issue.raw['fields']['customfield_38693']:
        return issue.fields.customfield_38693
    else:
        return ''

def get_target_end(issue:Issue):
    if not hasattr(issue.fields, 'customfield_31591'):
        raise Exception('No Target End Field, add customfield_31591 in field list', issue.key)
    if issue.raw['fields']['customfield_31591']:
        return issue.fields.customfield_31591
    else:
        return ''

def get_original_estimate(issue:Issue):
    if not hasattr(issue.fields, 'aggregatetimeoriginalestimate'):
        raise Exception("No aggregatetimeoriginalestimate field, add aggregatetimeoriginalestimate in field list", issue.key)
    if issue.fields.aggregatetimeoriginalestimate:
        return (issue.fields.aggregatetimeoriginalestimate / 3600)
    else:
        return 0

def get_remaining_estimate(issue:Issue):
    if not hasattr(issue.fields, 'timeestimate'):
        raise Exception("No timeestimate field, add timeestimate in field list", issue.key)
    if issue.fields.timeestimate:
        return (issue.fields.timeestimate / 3600)
    else:
        return 0

def get_fb_committed_status(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38758'):
        raise Exception("No customfield_38758 field, add FB Committed Status in field list", issue.key)

    #print(issue.fields.customfield_38758)
    if issue.fields.customfield_38758:
        return issue.fields.customfield_38758.value
    else:
        return ""

def getOrgEstimate(issue:Issue):
    ret = getOriginalEstimate(issue)

    if ret:
        return ret
    else:
        return getSumOriginalEstimate(issue)


def getOriginalEstimate(issue:Issue):
    # Original Estimation
    # print(issue.fields.timeoriginalestimate)
    if str(issue.fields.timeoriginalestimate) == "None":
        ret = ""
    else:
        e = int(issue.fields.timeoriginalestimate) / 3600
        ret = "%d" % e
    return ret

def getSumOriginalEstimate(issue:Issue):
    if str(issue.fields.customfield_39191) == "None":
        ret = ""
    else:
        ret = getEffortSum(issue.fields.customfield_39191)
    return ret

def getEffortSum(effort):
    if effort.find('h') >= 0:
        ret = effort.split('h')[0]
    elif effort.find('m') >= 0:
        ret = effort.split('m')[0]
    elif effort.find('w') >= 0:
        ret = effort.split('w')[0]
    else:
        ret = '0'

    if float(ret) == 0:
        ret = ''
    return ret

def getTimeSpentL(issue:Issue):
    # Time Spent
    if not hasattr(issue.fields,'timespent'):
        return ''

    if not issue.fields.timespent:
        return ''

    if int(issue.fields.timespent) != 0:
        e = int(issue.fields.timespent) / 3600
        return "%d" % e
    else:
        return ''


def get_logged_effort(issue:Issue):
    #print(issue.fields.customfield_39190)
    if not hasattr(issue.fields, 'customfield_39190'):
        return ''
    if not issue.fields.customfield_39190:
        return ''

    effort = issue.fields.customfield_39190
    if effort.find('h') >= 0:
        ret = effort.split('h')[0]
    elif effort.find('m') >= 0:
        ret = effort.split('m')[0]
    elif effort.find('w') >= 0:
        ret = effort.split('w')[0]
    else:
        ret = effort

    return ret


def get_sum_logged_effort(issue:Issue):
    if not hasattr(issue.fields, 'customfield_39190'):
        raise Exception('No logged effort field, add customfield_39190 in field list', issue.key)

    effort = issue.fields.customfield_39190
    if not effort:
        return 0
    if effort.find('h') >= 0:
        ret = effort.split('h')[0].replace(',', '')
    else:
        raise Exception('Un-supported logged effort type, check in code', issue.key)

    if ret.find('.'):
        ret = ret.split('.')[0]
    return int(ret)

def get_sum_original_estimate(issue:Issue):
    if not hasattr(issue.fields, 'customfield_39191'):
        raise Exception('No original estimate field, add customfield_39191 in field list', issue.key)

    effort = issue.fields.customfield_39191
    if not effort:
        return 0

    if effort.find('h') >= 0:
        ret = effort.split('h')[0].replace(',', '')
    else:
        raise Exception('Un-supported original estimate type, check in code', issue.key)

    if ret.find('.'):
        ret = ret.split('.')[0]

    return int(ret)

def get_sum_remaining_estimate(issue:Issue):
    logged_effort = get_sum_logged_effort(issue)
    original_estimate = get_sum_original_estimate(issue)

    remaining_estimate = original_estimate - logged_effort
    return remaining_estimate

def getAggregateTimeSpent(issue:Issue):
    if not hasattr(issue.fields, 'aggregatetimespent'):
        return ''
    if not issue.fields.aggregatetimespent:
        return ''

    if int(issue.fields.aggregatetimespent) != 0:
        e = int(issue.fields.aggregatetimespent) / 3600
        return "%d" % e
    else:
        return ''


def get_aggregate_time_spend(issue:Issue):
    if not hasattr(issue.fields, 'aggregatetimespent'):
        raise Exception('No aggregatetimespent field, add aggregatetimespent in field list', issue.key)
    if not issue.fields.aggregatetimespent:
        return ''
    if int(issue.fields.aggregatetimespent) != 0:
        e = int(issue.fields.aggregatetimespent) / 3600
        return e
    else:
        return ''

def getTimeSpent(issue:Issue):
    if getTimeSpentL(issue) != '':
        return getTimeSpentL(issue)

    if getAggregateTimeSpent(issue) != '':
        return getAggregateTimeSpent(issue)

    if get_logged_effort(issue) != '':
        return get_logged_effort(issue)

def getRemainEffort(issue:Issue):
    # Remaing Effort
    #print(issue.fields.aggregatetimeestimate)
    if str(issue.fields.aggregatetimeestimate) == "None":
        ret = ""
    else:
        e = int(issue.fields.aggregatetimeestimate)/3600
        ret = "%d"%e
    return ret

def get_time_spent_for_quality(issue:Issue):
    if get_aggregate_time_estimate(issue) != '':
        return get_aggregate_time_estimate(issue)

    if get_logged_effort(issue) != '':
        return get_logged_effort(issue)

def get_aggregate_time_estimate(issue:Issue):
    if not hasattr(issue.fields, 'aggregatetimeestimate'):
        raise Exception('No aggregatetimeestimate field, add aggregatetimeestimate in field list', issue.key)

    if issue.fields.aggregatetimeestimate:
        if int(issue.fields.aggregatetimeestimate) != 0:
            return int(issue.fields.aggregatetimeestimate)/3600
    return ''

def getActiveType(issue:Issue):
    # Activity Type
    #print("Active Type:",issue.raw['fields']['customfield_38750'])

    if issue.raw['fields']['customfield_38750']:
        actType= issue.raw['fields']['customfield_38750']['value']
    else:
        actType=""
    return actType

def get_active_type(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38750'):
        raise Exception('No active type field, add customfield_38750 in field list', issue.key)
    if issue.raw['fields']['customfield_38750']:
        actType= issue.raw['fields']['customfield_38750']['value']
    else:
        actType=""
    return actType


def getCompetenceArea(issue:Issue):
    # Competence Area
    #print("Competence Area:",issue.raw['fields']['customfield_38750'])
    if issue.raw['fields']['customfield_38690']:
        ca= issue.raw['fields']['customfield_38690']['value']
    else:
        ca=""
    return ca

def get_competence_area(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38690'):
        raise Exception('No competence area field, add customfield_38690 in field list', issue.key)
    if issue.raw['fields']['customfield_38690']:
        ca= issue.raw['fields']['customfield_38690']['value']
    else:
        ca=""
    return ca

def updateActivityType(issue:Issue):
    if isFs1taItem(issue):
        issue.update({'customfield_38750':{'value': ACTIVITY_TYPE_FS1TA}})
    elif isCfamCp1Item(issue) or isCfamCp2Item(issue):
        issue.update({'customfield_38750': {'value': ACTIVITY_TYPE_SFS}})
    else:
        raise Exception('Not a valid A&S CA, key - %s summary - '%(issue.key,issue.fields.summary))

def updateSpecificationType(issue:Issue):
    if isFs1taItem(issue):
        issue.update({'customfield_38753':{'value': SPEC_TYPE_FS1TA}})
    elif isCfamCp1Item(issue):
        issue.update({'customfield_38753': {'value': SPEC_TYPE_CP1}})
    elif isCfamCp2Item(issue):
        issue.update({'customfield_38753': {'value': SPEC_TYPE_CP2}})
    else:
        raise Exception('Not a valid A&S CA, key - %s summary - '%(issue.key,issue.fields.summary))

def isFs1taItem(issue:Issue):
    summary = issue.fields.summary
    if summary.find('FS1TA') > 0:
        return True
    else:
        return False

def isCfamCp1Item(issue:Issue):
    summary = issue.fields.summary
    if (summary.find('CP1') > 0 and summary.find('CFAM') > 0):
        return True
    else:
        return False

def isCfamCp2Item(issue:Issue):
    summary = issue.fields.summary
    if (summary.find('CP2') > 0 and summary.find('CFAM') > 0):
        return True
    else:
        return False

def getAssigneeForDomain(domain:str):
    if domain not in DOMAIN_LIST:
        raise Exception("Invalid domain name", domain)
    assigneeList={
        'SiSo':'chuxia',
        'CallHandling':'anbn',
        'QoSEndUserExp':'tgodard',
        'RadioPerf':'tgodard',
        'PerfCapa':'djupsund',
        'Cloud':'l14zhou',
        'E2EOperability-Basic':'burzawa',
		'E2EOperability-RNL':'pbronzin',
        'E2EOperability-Sec':'huet6',
        'E2EOperability-Sync':'huet6',
        'E2ETrs-Basic':'metsala',
        'E2ETrs-Sec':'huet6',
        'BB_HWI':'xizhou',
        'RU_HWI':'dems18z4',
        'SmallCells':'qa4439'
    }
    return assigneeList[domain]

def get_assignee_for_domain(domain):
    if domain.lower() not in domain_list.keys():
        raise Exception("Invalid domain name", domain)
    assignee_list = {
        'SiSo': 'chuxia',
        'CallHandling': 'anbn',
        'QoSEndUserExp': 'tgodard',
        'RadioPerf': 'tgodard',
        'PerfCapa': 'djupsund',
        'Cloud': 'l14zhou',
        'E2EOperability-Basic': 'burzawa',
		'E2EOperability-RNL': 'pbronzin' ,
        'E2EOperability-Sec': 'huet6',
        'E2EOperability-Sync': 'huet6',
        'E2ETrs-Basic': 'metsala',
        'E2ETrs-Sec': 'huet6',
        'BB_HWI': 'xizhou',
        'RU_HWI': 'dems18z4',
        'SmallCells': 'qa4439'
    }
    return assignee_list[domain]

def updateAssignee(issue:Issue, domain:str=''):
    if domain == '':
        domain = get_domain(issue)
    name=getAssigneeForDomain(domain)
    if name:
        issue.update({'assignee':{'name': name}})

def update_contact_person(issue:Issue, contact):
    issue.update({'customfield_38698':[{'name': contact}]})

def create_new_system_item(jira:JIRA, issue:Issue):
    if issue.fields.issuetype.name != ISSUE_TYPE_FT_L:
        raise Exception("Given Issue must be a Customer Feature", issue.fields.issuetype)
    old_childs = get_child_items(jira, jira.issue(issue.key))

    transitions = jira.transitions(issue)
    for t in transitions:
        #print(t['id'],t['name'])
        if t['name'] == 'New SI':
            jira.transition_issue(issue, t['id'])

    new_childs=get_child_items(jira, jira.issue(issue.key))
    for child in new_childs:
        if child not in old_childs:
            return child
    return None

def create_new_entity_item(jira:JIRA, issue:Issue):
    if issue.fields.issuetype.name != ISSUE_TYPE_SI_L:
        raise Exception("Given Issue must be a System Item", issue.fields.issuetype)
    old_childs=get_child_items(jira, jira.issue(issue.key))

    transitions = jira.transitions(issue)
    for t in transitions:
        #print(t['id'],t['name'])
        if t['name'] == 'New EI':
            jira.transition_issue(issue, t['id'])
            break
    new_childs=get_child_items(jira, jira.issue(issue.key))
    for child in new_childs:
        if child not in old_childs:
            return child
    return None

def create_new_ca_item(jira:JIRA, issue:Issue):
    if issue.fields.issuetype.name != ISSUE_TYPE_EI_L:
        raise Exception("Given Issue must be a Entity Item", issue.fields.issuetype)
    domain = get_domain(issue)
    if not domain:
        raise Exception('Domain missing', domain)
    #print(getDomainCompetenceArea()[domain])

    old_childs = get_child_items(jira, jira.issue(issue.key))
    transitions = jira.transitions(issue)
    for t in transitions:
        #print(t['id'],t['name'])
        if t['name'] == 'New CA Item':
            jira.transition_issue(issue, t['id'],
                                  fields={'customfield_38690': {'value': DOMAIN_CA_MAP[domain]}})
    new_childs=get_child_items(jira, jira.issue(issue.key))
    for child in new_childs:
        if child not in old_childs:
            return child
    return None

def get_sta_item(jira:JIRA, feature_item:Issue): # get system technical analysis item via feature item
    if not hasattr(feature_item.fields, 'issuetype'):
        raise Exception('Add issuetype in filed list', feature_item.key)

    if feature_item.fields.issuetype.name != ISSUE_TYPE_FT_L:
        raise Exception("Given Issue is not a Customer Feature", feature_item.fields.issuetype.name, feature_item.key)

    for issue_linked in feature_item.fields.issuelinks:
        if (issue_linked.type.name == 'Estimate') and hasattr(issue_linked, 'outwardIssue'):
            return jira.issue(issue_linked.outwardIssue.key, fields=['summary', 'customfield_38690', 'customfield_38702', 'issuetype', 'status', 'issuelinks'])
    return None

def get_sta_item_via_feature_id(jira:JIRA, feature_id:str): # get system technical analysis item via feature id
    jql = 'issueFunction in portfolioChildrenOf("type = \'Customer Feature\' AND summary ~ %s") AND issuetype = "System Technical Analysis" '%feature_id
    sta_list = jira.search_issues(jql, maxResults=1, validate_query=True, fields=['summary', 'customfield_38690', 'customfield_38702', 'issuetype', 'status', 'issuelinks'])
    if sta_list:
        return sta_list[0]
    else:
        return None

def create_sta_item(jira:JIRA, feature_item:Issue):# create system technical analysis item
    if feature_item.fields.issuetype.name != ISSUE_TYPE_FT_L:
        raise Exception("Given Issue is not a Customer Feature", feature_item.fields.issuetype.name, feature_item.key)

    transitions = jira.transitions(feature_item)
    for t in transitions:
        if t['name'] == 'New STA':
            jira.transition_issue(feature_item, t['id'])
    return get_sta_item(jira, jira.issue(feature_item.key, fields=['summary', 'issuetype', 'issuelinks']))

def get_eta_item(jira:JIRA, sta_item:Issue): # get entity technical analysis item via system technical analysis item
    if sta_item.fields.issuetype.name != ISSUE_TYPE_STA_L:
        raise Exception("Given Issue is not a Customer Feature", sta_item.fields.issuetype.name, sta_item.key)

    for issue_linked in sta_item.fields.issuelinks:
        if (issue_linked.type.name == 'Estimate') and hasattr(issue_linked, 'outwardIssue'):
            return jira.issue(issue_linked.outwardIssue.key, fields=['summary', 'customfield_38690', 'customfield_38702', 'issuetype', 'status', 'issuelinks'])
    return None

def get_eta_item_via_feature_id(jira:JIRA, feature_id:str):# get entity technical analysis item via feature id
    jql = 'issueFunction in portfolioChildrenOf("type = \'Customer Feature\' AND \'Feature ID\' ~ %s")  AND issuetype = "Entity Technical Analysis"  '%feature_id
    eta_list = jira.search_issues(jql, maxResults=1, validate_query=True, fields=['summary', 'customfield_38690', 'customfield_38702', 'issuetype', 'status', 'issuelinks'])
    if eta_list:
        return eta_list[0]
    else:
        return None

def create_eta_item(jira:JIRA, sta_item:Issue):# create entity technical analysis item
    if sta_item.fields.issuetype.name != ISSUE_TYPE_STA_L:
        raise Exception("Given Issue is not a system technical analysis item", sta_item.fields.issuetype.name, sta_item.key)

    transitions = jira.transitions(sta_item)
    for t in transitions:
        if t['name'] == 'New ETA':
            jira.transition_issue(sta_item, t['id'])
            return get_eta_item(jira, jira.issue(sta_item.key, fields=['summary', 'issuetype', 'issuelinks']))
    return None

def get_ee_item(jira:JIRA, eta_item:Issue, competence_area):
    if eta_item.fields.issuetype.name != ISSUE_TYPE_ETA_L:
        raise Exception("Given Issue is not an entity technical analysis item", eta_item.fields.issuetype.name, eta_item.key)

    for issue_linked in eta_item.fields.issuelinks:
        if (issue_linked.type.name == 'Estimate') and hasattr(issue_linked, 'outwardIssue'):
            issue = jira.issue(issue_linked.outwardIssue.key, fields=['summary', 'customfield_38690', 'customfield_38702', 'issuetype', 'status', 'issuelinks'])
            if get_competence_area(issue) == competence_area:
                return issue
    return None

def create_ee_item(jira:JIRA, eta_item:Issue, competence_area):
    if eta_item.fields.issuetype.name != ISSUE_TYPE_ETA_L:
        raise Exception("Given Issue is not an entity technical analysis item", eta_item.fields.issuetype.name, eta_item.key)
    transitions = jira.transitions(eta_item)
    for t in transitions:
        if t['name'] == 'New EE':
            #print(competence_area)
            jira.transition_issue(eta_item, t['id'], fields={'customfield_38690': {'value': competence_area}})
            return get_ee_item(jira, jira.issue(eta_item.key, fields=['summary', 'issuetype', 'issuelinks']), competence_area)
    return None

def getFs1taSystemItem(jira:JIRA, featureItem:Issue):
    if featureItem.fields.issuetype.name != ISSUE_TYPE_FT_L:
        raise Exception("Given Issue is not a Customer Feature", featureItem.fields.issuetype.name, featureItem.key)

    childs = get_child_items(jira, featureItem)
    for child in childs:
        if isFs1taItem(child):
            return child
    return None

def getFs1taEntityItem(jira:JIRA, fs1taSi:Issue):
    if fs1taSi.fields.issuetype.name != ISSUE_TYPE_SI_L:
        raise Exception("Given Issue is not a System Item", fs1taSi.fields.issuetype.name, fs1taSi.key)
    childs = get_child_items(jira, fs1taSi)
    for child in childs:
        if isFs1taItem(child):
            return child
    return None

def getFs1taCAItem(jira:JIRA, fs1taEi:Issue):
    if fs1taEi.fields.issuetype.name != ISSUE_TYPE_EI_L:
        raise Exception("Given Issue is not a Entity Item", fs1taEi.fields.issuetype.name, fs1taEi.key)
    childs = get_child_items(jira, fs1taEi)
    for child in childs:
        if isFs1taItem(child):
            return child
    return None

def getItemId(issue:Issue):
    if not hasattr(issue.fields,'customfield_38702'):
        raise Exception("No Item ID field, add customfield_38702 in field list")
    return issue.fields.customfield_38702

def get_item_id(issue:Issue):
    if not hasattr(issue.fields,'customfield_38702'):
        raise Exception("No Item ID field, add customfield_38702 in field list")
    return issue.fields.customfield_38702

def getCp1SystemItem(jira:JIRA, featureItem:Issue):
    if featureItem.fields.issuetype.name != ISSUE_TYPE_FT_L:
        raise Exception("Given Issue is not a Customer Feature", featureItem.fields.issuetype.name, featureItem.key)

    childs = get_child_items(jira, featureItem)
    for child in childs:
        if isCfamCp1Item(child):
            return child
    return None

def getCp1EntityItem(jira:JIRA, cp1Si:Issue):
    if cp1Si.fields.issuetype.name != ISSUE_TYPE_SI_L:
        raise Exception("Given Issue is not a System Item", cp1Si.fields.issuetype.name, cp1Si.key)
    childs = get_child_items(jira, cp1Si)
    for child in childs:
        if isCfamCp1Item(child):
            return child
    return None

def getCp1CaItem(jira:JIRA, cp1Ei:Issue):
    if cp1Ei.fields.issuetype.name != ISSUE_TYPE_EI_L:
        raise Exception("Given Issue is not a Entity Item", cp1Ei.fields.issuetype.name, cp1Ei.key)
    childs = get_child_items(jira, cp1Ei)
    for child in childs:
        if isCfamCp1Item(child):
            return child
    return None

def getIssueTypeShortName(issue:Issue):
    if issue.fields.issuetype.name == ISSUE_TYPE_FT_L:
        return ISSUE_TYPE_FT_S
    elif issue.fields.issuetype.name == ISSUE_TYPE_SI_L:
        return ISSUE_TYPE_SI_S
    elif issue.fields.issuetype.name == ISSUE_TYPE_EI_L:
        return ISSUE_TYPE_EI_S
    elif issue.fields.issuetype.name == ISSUE_TYPE_CA_L:
        return ISSUE_TYPE_CA_S
    else:
        raise Exception("getIssueTypeShortName exception, unsupported issue type", issue.fields.issuetype.name)

def get_sub_feature_si(jira:JIRA, feature_item:Issue, sub_feature_id:str):
    if feature_item.fields.issuetype.name != ISSUE_TYPE_FT_L:
        raise Exception("Given Issue is not a Customer Feature", feature_item.fields.issuetype.name, feature_item.key)

    if re.compile('^[A-Y]{1,2}$').search(sub_feature_id) is None:
        raise Exception("Invalid sub-feature Id. Id shall be A~Y", sub_feature_id)

    pattern=get_feature_id(feature_item)+"-"+sub_feature_id+"\s{0,1}[\s{0}|-].*"
    childs=get_child_items(jira, feature_item)
    for child in childs:
        if re.compile(pattern).search(child.fields.summary):
            return child
    return None

def getSubFtCp2EntityItem(jira:JIRA, systemItem:Issue, subFeatureId:str):
    if systemItem.fields.issuetype.name != ISSUE_TYPE_SI_L:
        raise Exception("Given Issue is not a Customer Feature", systemItem.fields.issuetype.name, systemItem.key)

    if re.compile('^[A-Y]{1,2}$').search(subFeatureId) is None:
        raise Exception("Invalid sub-feature Id. Id shall be A~Y", subFeatureId)

    pattern='%s\s{0,1}-\s{0,1}%s\s{0,1}-\s{0,1}CFAM\s{0,1}-\s{0,1}CP2\s{0,1}[\s{0}|-].*'%(get_feature_id(systemItem),subFeatureId)
    childs=get_child_items(jira, systemItem)
    for child in childs:
        if re.compile(pattern).search(child.fields.summary):
            return child
    return None

def getSubFtCp2CaItem(jira:JIRA, entityItem:Issue, subFeatureId:str):
    if entityItem.fields.issuetype.name != ISSUE_TYPE_EI_L:
        raise Exception("Given Issue is not a Entity Item", entityItem.fields.issuetype.name, entityItem.key)

    if re.compile('^[A-Y]{1,2}$').search(subFeatureId) is None:
        raise Exception("Invalid sub-feature Id. Id shall be A~Y", subFeatureId)

    pattern='%s\s{0,1}-\s{0,1}%s\s{0,1}-\s{0,1}CFAM\s{0,1}-CP2\s{0,1}[\s{0}|-].*'%(get_feature_id(entityItem),subFeatureId)
    childs=get_child_items(jira, entityItem)
    for child in childs:
        if re.compile(pattern).search(child.fields.summary):
            return child
    return None

def __CREATE_FS1TA_ITEM_ID(issue:Issue):
    name="%s-FS1TA"%get_feature_id(issue)
    return name

def __CREATE_CP1_ITEM_ID(issue:Issue, domain:str=''):
    issue_type = get_issue_type(issue)
    if issue_type == ISSUE_TYPE_CA_L:
        if domain == '':
            domain = get_domain(issue)
        name="%s-CFAM-CP1-%s"%(get_feature_id(issue), domain)
    else:
        name="%s-CFAM-CP1"%(get_feature_id(issue))
    return name

def __CREATE_SUB_FEATURE_ITEM_ID(issue:Issue, sub_feature:str):
    if sub_feature == '':
        raise Exception('Sub-feature must not be empty for sub-feature item', sub_feature)

    issue_type = get_issue_type(issue)

    if issue_type != ISSUE_TYPE_SI_L:
        raise Exception('Only support create system item for sub-feature', issue_type, sub_feature)

    name="%s-%s"% (get_feature_id(issue), sub_feature)
    return name

def __CREATE_CFAM_CP2_ITEM_ID__(issue:Issue, domain:str, subFeature:str):
    if subFeature == '':
        raise Exception('Sub-feature must not be empty for CP2', subFeature)
    issuetype=getIssueTypeShortName(issue)
    if issuetype == ISSUE_TYPE_SI_S:
        raise Exception("Shall not create System Item for CFAM-CP2", issuetype)
    elif issuetype == ISSUE_TYPE_EI_S:
        name="%s-%s-CFAM-CP2"% (get_feature_id(issue), subFeature)
    elif issuetype == ISSUE_TYPE_CA_S:
        if domain == '':
            domain = get_domain(issue)
        name="%s-%s-CFAM-CP2-%s"% (get_feature_id(issue), subFeature, domain)
    return name

def createItemId(issue:Issue, workType:str, domain:str='', subFeature:str=''):
    if (not issue) or (not workType) :
        raise Exception("Empty fields Issue:%s, TYPE:%s"%(issue, workType))
    if workType == WORK_TYPE_FS1TA:
        return __CREATE_FS1TA_ITEM_ID(issue)
    elif workType == WORK_TYPE_CP1:
        return __CREATE_CP1_ITEM_ID(issue, domain)
    elif workType == WORK_TYPE_CP2:
        return __CREATE_CFAM_CP2_ITEM_ID__(issue, domain, subFeature)
    elif workType == WORK_TYPE_SUB:
        return __CREATE_SUB_FEATURE_ITEM_ID(issue, subFeature)
    else:
        raise Exception("Invalid A&S Item Type for the call", workType)
    return ''

def expected_sub_ft_summary(feature:str, sub_feature:str, title:str):
    summary = "%s-%s - %s"%(feature, sub_feature, title)
    return summary

def expected_cp2_item_summary(feature:str, sub_feature:str, title:str):
    summary = "%s-%s-CFAM-CP2 - %s"%(feature, sub_feature, title)
    return summary

def expected_cp1_item_summary(feature:str, title:str):
    summary = "%s-CFAM-CP1 - %s"%(feature, title)
    return summary

def expected_fs1ta_item_summary(feature:str, title:str):
    summary = "%s-FS1TA - %s"%(feature, title)
    return summary

def parse_sub_feature_id(summary:str):
    import re

    if summary.find("FS1TA") > 0:
        return '', ''
    if summary.find("CFAM") > 0:
        return '', ''

    match = re.compile('^5GC00[0-9]{4}\s{0,1}-\s{0,1}([A-Y]{1,2})\s{0,1}-{0,1}\s{0,1}(.*)').search(summary)
    if not match:
        return '', ''
    return match.groups()

def expected_activity_type(work_type:str):
    if work_type in [WORK_TYPE_FS1TA]:
        return ACTIVITY_TYPE_FS1TA
    elif work_type in [WORK_TYPE_CP1, WORK_TYPE_CP2]:
        return ACTIVITY_TYPE_SFS
    else:
        raise Exception("INVALID work type given", work_type)

def expected_specification_type(work_type:str):
    if work_type == WORK_TYPE_FS1TA:
        return SPEC_TYPE_FS1TA
    elif work_type == WORK_TYPE_CP1:
        return SPEC_TYPE_CP1
    elif work_type == WORK_TYPE_CP2:
        return SPEC_TYPE_CP2
    else:
        raise Exception("INVALID work type given", work_type)

def get_fs_status(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38705'):
        raise Exception('No FS Status and Date field, add customfield_38705 in field list')

    if issue.fields.customfield_38705:
        return issue.fields.customfield_38705
    else:
        return ''


def get_issue_type(issue):
    if not hasattr(issue.fields, 'issuetype'):
        raise Exception('No issuetype field, add issuetype in field list ')

    return issue.fields.issuetype.name

def get_requirement_area(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38712'):
        raise Exception('No Requirement Area field, add customfield_38712 in field list')
    if issue.fields.customfield_38712:
        return issue.fields.customfield_38712
    else:
        return ''

def updateFeatureId(issue:Issue, feature:str):
    if re.compile('^5GC00[0-9]{4}$').search(feature) is None:
        raise Exception('Invalide Feature Id', feature)
    issue.update({'customfield_37381',feature})

def updateDomain(issue:Issue, domain:str):
    if domain not in DOMAIN_LIST:
        raise Exception("Invalid requirement area given", domain)
    issue.update({'customfield_38712': domain})

def update_requirement_area(issue:Issue, requirement_area:str):
    #domain = parse_requirement_area(requirement_area)
    if requirement_area.lower() not in domain_list:
        raise Exception('Invalide requirement area', requirement_area)
    issue.update({'customfield_38712': requirement_area})

domain_list={
    'siso':'SiSo',
    'callhandling':'CallHandling',
    'qosenduserexp':'QoSEndUserExp',
    'radioperf':'RadioPerf',
    'perfcapa':'PerfCapa',
    'cloud':'Cloud',
    'e2eoperability-basic':'E2EOperability-Basic',
	'e2eOperability-RNL':'E2EOperability-RNL',
    'e2eoperability-sec':'E2EOperability-Sec',
    'e2eoperability-sync':'E2EOperability-Sync',
    'e2etrs-basic':'E2ETrs-Basic',
    'e2etrs-sec':'E2ETrs-Sec',
    'bb_hwi':'BB_HWI',
    'ru_hwi':'RU_HWI',
    'smallcells':'SmallCells'
}

def parse_requirement_area(requirement_area:str):
    reobj = re.compile('(FAO .*,){0,1}\s{0,1}A&S\s{0,1}(.*){0,1}')
    match = reobj.search(requirement_area)
    if not match:
        raise Exception('Unrecognized requirement area', requirement_area)
    else:
        return match.groups()[1]

def get_domain_old(issue:Issue):
    requirement_area = get_requirement_area(issue)

    if not requirement_area:
        return requirement_area

    requirement_area = requirement_area.lstrip().rstrip()
    if requirement_area.find('A&S') >= 0:
        domain = parse_requirement_area(requirement_area)
    elif requirement_area.find('FAO') >= 0 and requirement_area.find('A&S') < 0:
        return ''
    else:
        domain = requirement_area

    if domain.lower() not in domain_list.keys():
        raise Exception('Invalide requirement area', issue.key, domain, requirement_area)

    return domain_list[domain.lower()]

def get_domain(issue:Issue):
    requirement_area = get_requirement_area(issue).lstrip().rstrip()

    if not requirement_area:
        return ''

    if requirement_area.lower() not in domain_list.keys():
        print('Invalid requirement area', issue.key, requirement_area, get_summary(issue))

    return requirement_area

def get_solution_area(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38711'):
        raise Exception('No Requirement Area field, add customfield_38711 in field list')
    if issue.fields.customfield_38711:
        return str(issue.fields.customfield_38711).lstrip().rstrip()
    else:
        return ''

def get_fs0_ee(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38737'):
        raise Exception('No FS0 EE field, add customfield_38737 in field list')

    if issue.fields.customfield_38737:
        return (int(issue.fields.customfield_38737))
    else:
        return 0

def get_fs2_ee(issue:Issue):
    if not hasattr(issue.fields, 'customfield_38692'):
        raise Exception('No FS2 EE field, add customfield_38692 in field list')

    if issue.fields.customfield_38692:
        return (int(issue.fields.customfield_38692))
    else:
        return 0

def get_latest_comment(jira, issue:Issue):
    item = jira.issue(issue.key, fields=['comment'])
    num_of_comment = len(item.fields.comment.comments)
    if num_of_comment == 0:
        return  ''

    id = item.fields.comment.comments[num_of_comment-1].id
    comment = jira.comment(item, id)

    match = re.compile('^(\d{4}\-\d{2}-\d{2})T.*').search(comment.created)
    t = match.groups()[0]

    return t + " " + comment.body

def update_fb_committed_status(issue, commitment):
    issue.update({'customfield_38758': {'value': commitment}})

def create_epic_for_ca(jira, ca_item):
    if ca_item.fields.issuetype.name != ISSUE_TYPE_CA_L:
        raise Exception("Given Issue must be a CA Item", ca_item.fields.issuetype)
    url = 'https://jiradc.int.net.nokia.com/secure/ExocetOperation!default.jspa?operationId=368&sourceIssueId=%s' % ca_item.id
    jira._session.get(url=url)

    epic = get_new_epic_for_ca(jira, ca_item)
    if epic:
        return epic
    else:
        return None

def get_new_epic_for_ca(jira, ca_item):
    if ca_item.fields.issuetype.name != ISSUE_TYPE_CA_L:
        raise Exception("Given Issue must be a CA Item", ca_item.fields.issuetype)

    jql = 'issueFunction in portfolioChildrenOf("key = %s") AND "Contact Person" is EMPTY'%str(ca_item.key)
    epic_list = jira.search_issues(jql, maxResults=1)
    if len(epic_list):
        return epic_list[0]
    else:
        return None

def get_epic_for_ca(jira, ca_item):
    if ca_item.fields.issuetype.name != ISSUE_TYPE_CA_L:
        raise Exception("Given Issue must be a CA Item", ca_item.fields.issuetype)

    jql = 'issueFunction in portfolioChildrenOf("key = %s") AND type = Epic ' % str(ca_item.key)
    epic_list = jira.search_issues(jql, maxResults=1)

    if len(epic_list):
        return epic_list
    else:
        return None

if __name__ == '__main__':
    #import os
    #os.environ['https_proxy']='http://192.168.2.99:9090'
    #os.environ['http_proxy']='http://192.168.2.99:9090'

    #url = 'https://jiradc.int.net.nokia.com/secure/ExocetOperation!default.jspa?operationId=368&sourceIssueId=%s'%issue.id
    #jira._session.get(url=url)


    #jira = init_jira_connection()
    #key = 'FPB-395427'
    #issue = jira.issue(key)

    #print(get_target_end(issue))

    #jira = init_jira_connection()
    #key = 'FPB-342330'
    #issue = jira.issue(key, fields=['summary'])
    #print(get_summary(issue))
    #summary = get_summary(issue)
    #print(summary)
    summary = '5GC002509-CFAM-CP1 - Baseband block FR1 TDD eCPRI - 4 Cells 4 layers 10GE'
    match = re.compile('^(5GC00[0-9]{4}|CB00[0-9]{4}-5G)(\s{0,1}-\s{0,1}CFAM\s{0,1}-\s{0,1}CP1)\s{0,1}-{0,1}(.*)').search(summary)
    if match:
        print(match.groups())